本篇是接續一、用skeleton code解釋tensorflow model程式執行方式(tf.keras) ep.3,ep.2與ep.3都在講第4段程式架構的project的資料夾結構,今天這篇一樣要繼續講第4段,但會開始進入程式虛擬碼講解部分。
繼簡單介紹和比較過,同任務不同dataset之間的差異,還有總結深度學習完整1 run的流程。
接著就是從個人觀點去建議,一個project的結構如何編排,才能讓後續的模型分析工作,得以順利進行。
在ep.2,首先講了project分開的時機,還有project內的資料夾安排,有放模型架構的資料夾core/
,放處理資料程式的資料夾datasets
,還有在ep.3有講到紀錄訓練資訊的資料夾logs/
和models/
。
今天ep.4就要接著從訓練主程式train.py
開始說起。讓我們開始吧。
在開始繼續講我的訓練主程式的code編排方式之前,先放一下到目前為止,一個project內要包含的資料夾與程式架構。
.
└── project1
├── core/
| ├── unet.py
| ├── backbone/
| └── ...
├── datasets/
| ├── DATASET_NAME
| | ├── annotations/
| | ├── data/
| | └── tfrecords
| | ├──DATASET_NAME_pred.tfrecord
| | ├──DATASET_NAME_train.tfrecord
| | └──DATASET_NAME_val.tfrecord
| ├── build_DATASET_NAME_to_tfrecord.py
| ├── build_data.py
| ├── data_generater.py
| ├── preprocesses.py
| ├── tfrecord2image_DATASET_NAME_format.py
| └── ...
├── logs/
| ├── MODEL_NAME_WITH_CONFIG.log
| └── ...
├── models/
| └── MODEL_NAME_WITH_CONFIG/
| | ├── checkpoint/
| | | ├── weights-improvement-0.86.hdf5
| | | ├── weights-improvement-0.94.hdf5
| | | └── ...
| | ├── ~~M_N_acc.png~~
| | └── ~~M_N_loss.png~~
| └── ...
├── evaluate.py
├── predict.py
├── README.md
└── train.py
train.py
訓練主程式的功能,就是一執行它,就會取得一個模型架構,並根據參數設定及所喂進的資料進行訓練。
也就是說,在這支程式裡需要能接受hyper parameter設定,根據接收到的參數進行模型選取和loss及optimizer等設定,然後還要取得訓練及驗證資料。
接下來我將開始介紹code編排,會有實際的python程式與虛擬碼交錯。
1 # 取得hyper parameter
取得hyper parameter有很多種辦法,一種是tensorflow團隊會使用的common參數與tf的flags來管理與設定參數,顧名思義,common的參數都是那種常見且大部分模型都共通的參數,想多了解tensorflow團隊的project的可以走這(tensorflow/research);
import os
import tensorflow as tf
flags = tf.app.flags
flags.DEFINE_integer('batch_size', 1,
'model update after go through "batch_size" data.')
flags.DEFINE_integer('epochs', 1,
'training will go through whole dataset "epochs" times.')
flags.DEFINE_float('learning_rate', 1e-4,
'initial learning rate.')
flags.DEFINE_string('loss_fn', '',
'[BCE, MSE, dice, ...]')
flags.DEFINE_string('model_name', '',
'name of training model')
flags.DEFINE_string('optimizer', '',
'[adam, sgd, ...]')
flags.DEFINE_string('train_tfrecords_path', '',
'tfrecord path contains tfrecord with specific file pattern name.')
flags.DEFINE_string('val_tfrecords_path', '',
'tfrecord path contains tfrecord with specific file pattern name.')
FLAGS = flags.FLAGS
def main(_):
print(FLAGS.batch_size)
if __name__ == '__main__':
if not os.path.exists('./logs'):
os.makedirs('./logs')
tf.app.run()
tensorflow的框架自帶處理command line參數的API tf.app.flags,個人認為使用上蠻方便的,使用的話,程式寫法會有一個共同的起始點tf.app.run()需要跑,就像上方程式這樣,tf.app.run()一執行,預設會去執行檔案中的main() function。
程式執行方法是在command line執行時,把每個參數加上2個dash及數值
--batch_size 256
。
tensorflow 自帶的app.flags有個美中不足之處是,我目前沒有找到他可以跟jupyter notebook一起運行的方式,有時候要測試程式寫法,用jupyter比較快速方便,那這時我的參數管理就會改用argparse,並寫好每個參數的預設值。
import os
import argparse
import tensorflow as tf
parser = argparse.ArgumentParser()
parser.add_argument('--model_name', default='MODEL_NAME', \
help='name of training model')
parser.add_argument('--tfrecords_path',default='datasets/MODEL_NAME/tfrecords/MODEL_NAME_val.tfrecord', \
help='test tfrecord')
parser.add_argument('--batch_size', default=10,
help='model update after go through "batch_size" data.', type=int)
parser.add_argument('--learning_rate', default=1e-4, \
help='initial learning rate.', type=float)
parser.add_argument('--loss_fn', default='dice', \
help='[BCE, MSE, dice, ...]')
parser.add_argument('--optimizer', default='sgd',
help='[adam, sgd, ...]')
FLAGS = parser.parse_args(args=[])
def main(_):
print(FLAGS.batch_size)
if __name__ == '__main__':
tf.app.run()
這樣寫的話可以只改動管理參數的package,而不用動到程式裡面的參數。
def main(_):
## prepare arguments
## prepare data according to arguments
## prepare model architecture according to arguments
## configurate model with arguments
## prepare arguments of saving model information
## training model in keras way
if __name__ == '__main__':
## prepare directories of logs/, models/MODEL_NAME/, models/MODEL_NAME/checkpoint
## record hyper parameter
接著main()需要做到這些5件事情:
(1) prepare arguments:將執行時設置的參數,整理成方便處理data程式及處理model程式取得的形式,個人是都用dictionary型態。
(2) 透過datasets/data_generator.py
取得訓練與驗證資料,我在ep.2有簡略的描述過這支程式的用途,詳細程式後續再提。
(3) 透過core/
取得模型架構,取得模型空殼
(4) 模型除了架構之外,還有loss、optimizer這類運算的設定需要補上,拉出來到main()這裏,撰寫是會比較具有靈活性
(5) 儲存訓練結果是非常重要的一件事,如何儲存以及要存下哪些資訊,在訓練前都要先決定。
(6) 最後就是訓練的部分。
接下來就會完善各部分程式,並向大家介紹tf.data與tf.keras要如何結合使用。
不過可能要等明天了,我對於接下來要怎麼呈現,還是有點混亂,希望到目前為止還算順暢。
如果你看到這裡,想謝謝你的耐心,如果能留言鼓勵我,會成為我很大的動力的。